
#include "apdu_lib_mac_mgr.h"
#include "apdu_lib_common.h"

#include "../apdu.core/apdu.h"

#include "../../mk_lib/mk_auto_ptr.h"
#include "../../mk_lib/mk_utility.h"

#include <stdlib.h>
#include <string.h>
#include "../apdu.algo/mac.h"

extern int	g_sw;

int app_mac_init( HANDLE devHandle, int app_id, int container_id, int key_id, unsigned long alg_id, 
				 unsigned char * iv, int iv_len, unsigned long padding_type, unsigned long feed_bit_len )
{
	apdu * newApdu  =  NULL;
	newApdu = get_mac_mgr()->create_apdu_mac_init(app_id, container_id, key_id, alg_id,
				iv, iv_len, padding_type, feed_bit_len);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	return 0;
}

int app_mac( HANDLE devHandle, int app_id, int container_id, int key_id, 
			unsigned char * input_data, int input_len, 
			unsigned char * mac_result, int * mac_len )
{
	apdu * newApdu  =  NULL;
	newApdu = get_mac_mgr()->create_apdu_mac(app_id, container_id, key_id, input_data, input_len);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	int data_len = 0;
	unsigned char * data = newApdu->get_response_data(&data_len);
	if(*mac_len < data_len)
	{
		return 3;
	}
	*mac_len = data_len;
	memcpy(mac_result, data, data_len);
	return 0;
}

int app_mac_update( HANDLE devHandle, int app_id, int container_id, int key_id,
				   unsigned char * input_data, int input_len )
{
	apdu * newApdu  =  NULL;
	newApdu = get_mac_mgr()->create_apdu_mac_update(app_id, container_id, key_id, input_data, input_len);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	return 0;
}

int app_mac_final( HANDLE devHandle, int app_id, int container_id, int key_id,
				  unsigned char * input_data, int input_len, 
				  unsigned char * mac_result, int * mac_len )
{
	apdu * newApdu  =  NULL;
	newApdu = get_mac_mgr()->create_apdu_mac_final(app_id, container_id, key_id, input_data, input_len);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	int data_len = 0;
	unsigned char * data = newApdu->get_response_data(&data_len);
	if(*mac_len < data_len)
	{
		return 3;
	}
	*mac_len = data_len;
	memcpy(mac_result, data, data_len);
	return 0;
}
